package com.jason.auto.service.impl;

import com.jason.auto.common.BizException;
import com.jason.auto.common.ResultCode;
import com.jason.auto.model.User;
import com.jason.auto.proto.cs.user.UserEditRequest;
import com.jason.auto.proto.cs.user.UserQueryRequest;
import com.jason.auto.repository.UserRepository;
import com.jason.auto.service.UserService;
import com.jason.auto.util.MD5Util;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.*;

@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserRepository userRepository;

    @Override
    public User findUserById(Long userId) {
        return userRepository.findOne(userId);
    }

    @Override
    public Page<User> findUserByPage(UserQueryRequest userQueryRequest) {
        //前端的 page从1开始，后端查询应该从0开始
        Pageable pageable = new PageRequest(userQueryRequest.getPage() - 1, userQueryRequest.getLimit(), Sort.Direction.ASC, "id");
        Page<User> userPage = userRepository.findAll((Root<User> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) -> {
            List<Predicate> list = new ArrayList<Predicate>();
            if (Objects.isNull(userQueryRequest)) {
                return null;
            }
            if (!StringUtils.isEmpty(userQueryRequest.getName())) {
                list.add(criteriaBuilder.like(root.get("name").as(String.class), "%" + userQueryRequest.getName() + "%"));
            }
            if (!Objects.isNull(userQueryRequest.getRoleId()) && userQueryRequest.getRoleId() != 0) {
                list.add(criteriaBuilder.equal(root.get("roleId").as(String.class), userQueryRequest.getRoleId()));
            }
            return criteriaBuilder.and(list.toArray(new Predicate[list.size()]));
        }, pageable);
        return userPage;
    }

    @Override
    public void delete(Long userId) {
        userRepository.delete(userId);
    }

    @Override
    public void batchDelete(List<Long> userIds) {
        userRepository.batchDelete(userIds);
    }

    @Override
    public void edit(UserEditRequest userEdit) {
        User user;
        if (!StringUtils.isEmpty(userEdit.getId()) && userEdit.getId() != 0) {
            user = findUserById(userEdit.getId());
            if (Objects.isNull(user)) {
                throw new BizException(ResultCode.USER_NOT_FOUND);
            }
        } else {
            user = new User();
            user.setCreateTime(new Date());
            user.setPassword(MD5Util.MD5("123456"));
        }
        if (!StringUtils.isEmpty(userEdit.getName())) {
            User firstByNameAndIdNot = userRepository.findFirstByNameAndIdNot(userEdit.getName(), userEdit.getId());
            if (!Objects.isNull(firstByNameAndIdNot)) {
                throw new BizException(ResultCode.USER_NAME_EXIST);
            }
            user.setName(userEdit.getName());
        }
        if (!StringUtils.isEmpty(userEdit.getPhone())) {
            User firstByPhoneAndIdNot = userRepository.findFirstByPhoneAndIdNot(userEdit.getPhone(), userEdit.getId());
            if (!Objects.isNull(firstByPhoneAndIdNot)) {
                throw new BizException(ResultCode.USER_PHONE_EXIST);
            }
            user.setPhone(userEdit.getPhone());
        }
        user.setRoleId(userEdit.getRoleId());
        userRepository.save(user);
    }
}